#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>

#include "hash.h"

/*
  自己实现的Hash散列算法
  参考wikipedia上的Hash散列算法
 */
int chooseKey(void *pData, int iSize)
{
    /*
       推荐使用该散列算法!!
       这里是关键!!
       如果是自定义的数据结构
       则这里的赋值则将自定义数据结构中的Key值赋给pucKey
     */
    unsigned char *pucKey = pData;
    
    unsigned int   iHash  = 0;
    int            i      = 0;
    for ( ; i < strlen((char *)pucKey); i++)
    {
        iHash += pucKey[i];
        iHash += (iHash << 10);
        iHash ^= (iHash >> 6);
    }
    
    iHash += (iHash << 3);
    iHash ^= (iHash >> 11);
    iHash += (iHash << 15);

    return iHash % iSize;

} 


/*
  自己实现的Hash键值比较函数
 */
int compareKey(void *pData1, void *pData2)
{
#if 0
    return memcmp(pData1, pData2, sizeof(pData1));
#endif
    /*
       注意这个函数的返回结果表示的是两个Hash节点是否相同
       当然你可以定义两个Hash节点相同的”定义“就是两个Key相同
       如果是自定义的数据结构
       则这里的void *pData1和void *pData2是自定义数据结构中表示Key的指针
       然后根据自己的具体需要，定制Hash节点内容相同的算法实现
     */
    return strncmp((char *)pData1, (char *)pData2, sizeof(pData1));
}


int main()
{
   HASH_TABLE_T *pstHash = newHashTable(1, compareKey, chooseKey, NULL);

    if(pstHash == NULL)
    {
        printf("%s", "HashTable create failed!\n");
        exit(-1);
    }
    
    const char *pcStr[] = {
        "Accept:zh-cn,utf-8", 
        "User-Agent:Test1,Test2", 
        "Locale:A1,A2", 
        "Accept:en,us", 
        "Accept:en,us", 
        "Accept:us,en",
        "God",
        "Damnit",
        "Good",
        "OK?"
    };


    const char *pcKey = "Accept";
    int i = 0;
    for(; i < 10; i++)
    {
        printf("%s\n",pcStr[i]);
        if(addToHash(pstHash, (void *)pcStr[i]) == 0)
        {   
            printf("Add ok:%s\n", pcStr[i]);
        }
        else
        {
            printf("Add fail:%s\n", pcStr[i]);
        }
    }
  
    debugHash(pstHash); 

    printf("=================== findInHash Test ===================================\n");
#if 0
    char *pcRs = findInHash(pstHash, (void *)pcKey);

    if(pcRs != NULL)
    {
        printf("found %s match %s\n", pcRs, pcKey);
    }
    else
    {
        printf("%s not found\n", pcKey);
    }
#endif


    printf("=================== iterateHash Test ===================================\n");

    HASH_IT_T *pstHashIt = NULL;
    
    while (NULL != (pstHashIt = iterateHash(pstHash, pstHashIt)))
    {
        printf("[%3d]->%s\n", pstHashIt->iIndex, (char *)pstHashIt->pstBucket->pData);
    }

    printf("=================== resizeHash Test ===================================\n");
    
    pstHash = resizeHash(pstHash,20);
    
    if(pstHash != NULL)
    {
        printf("resizeHash OK! The new size of HASH_TABLE_T is %d\n", pstHash->iSize);
    }
    else
    {
        printf("resizeHash failed!");
    }
    
    debugHash(pstHash);

    printf("=================== removeHash Test ===================================\n");

    printf("before removeData call: HASH_TABLE_T has %d elements\n", pstHash->iElements);
    
    removeHash(pstHash, (void *)pcKey);

    printf("after removeData call: HASH_TABLE_T has %d elements\n", pstHash->iElements);

    printf("=================== deleteHash Test ===================================\n");

    deleteHash(pstHash, ENABLE_FREE_DATA_CB);

    
    return 0;
}
